package org.apache.derby.shared.common.info;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * @author ex_chenzy59
 * @since 2025/3/6
 *
 */
public class ProductVersionHolder {
    private static final int BAD_NUMBER = -1;
    private static final String ALPHA = "alpha";
    private static final String BETA = "beta";
    private String productName;
    private int majorVersion = BAD_NUMBER;
    private int minorVersion = BAD_NUMBER;
    private int maintVersion = BAD_NUMBER;
    private int drdaMaintVersion = BAD_NUMBER;
    private String buildNumber = "????";
    public final static int	MAINT_ENCODING = PropertyNames.MAINT_ENCODING;
    private Boolean isBeta;
    private String productVendorName;
    private String productTechnologyName;
    public String getProductName()
    {
        return productName;
    }
    public String getVersionBuildString(boolean withBuild)
    {
        return ProductVersionHolder.fullVersionString(majorVersion, minorVersion, maintVersion, isBeta(),
                withBuild ? buildNumber : null);
    }
    public int getMajorVersion() {return majorVersion;}
    public int getMinorVersion() {return minorVersion;}
    public int getDrdaMaintVersion() {return drdaMaintVersion; }
    public boolean isBeta() {return isBeta.booleanValue();}
    public String getBuildNumber() {return buildNumber;}
    public static String fullVersionString(int major, int minor, int maint, boolean isBeta, String build) {
        StringBuffer sb = new StringBuffer();
        sb.append(major);
        sb.append('.');
        sb.append(minor);
        sb.append('.');

        String preRelease = null;
        if (major == 5 && minor <= 2 && maint < MAINT_ENCODING){
            sb.append(maint);
            if (isBeta){
                preRelease = BETA;
            }
        }else{
            int fixPack = maint / MAINT_ENCODING;
            int bugVersion = maint % MAINT_ENCODING;
            sb.append(fixPack);
            sb.append('.');
            sb.append(bugVersion);

            if (fixPack == 0){
                preRelease = ALPHA;
            }else if (isBeta) {
                preRelease = BETA;
            }
        }

        if (preRelease != null){
            sb.append(' ');
            sb.append(preRelease);
        }if (build != null) {
            sb.append(" - (");

            sb.append(build);
            sb.append(')');
        }
        return sb.toString();
    }
    public static ProductVersionHolder getProductVersionHolderFromMyEnv(InputStream propertiesStream){
        if (propertiesStream == null){
            return null;
        }
        Properties p = new Properties();
        try {
            p.load(propertiesStream);
        } catch (IOException ioe) {
            System.out.println("IOE " + ioe.getMessage());
            //
            //This case is a bit ugly. If we get an IOException, we return
            //null. Though this correctly reflects that the product is not
            //available for use, it may be confusing to users that we swallow
            //the IO error here.
            return null;
        } finally {
            try {
                propertiesStream.close();
            } catch (IOException ioe2) {
            }
        }
        return getProductVersionHolder(p);
    }
    public static ProductVersionHolder
    getProductVersionHolder(Properties p)
    {
        String pvn = p.getProperty(PropertyNames.PRODUCT_VENDOR_NAME);
        String pn = p.getProperty(PropertyNames.PRODUCT_EXTERNAL_NAME);
        String ptn = p.getProperty(PropertyNames.PRODUCT_TECHNOLOGY_NAME);
        int v1 = parseInt(p.getProperty(PropertyNames.PRODUCT_MAJOR_VERSION));
        int v2 = parseInt(p.getProperty(PropertyNames.PRODUCT_MINOR_VERSION));
        int v3 = parseInt(p.getProperty(PropertyNames.PRODUCT_MAINT_VERSION));
        int v4 = parseInt(p.getProperty(PropertyNames.PRODUCT_DRDA_MAINT_VERSION));
        String bn = p.getProperty(PropertyNames.PRODUCT_BUILD_NUMBER);
        Boolean isBeta =
                Boolean.valueOf(p.getProperty(PropertyNames.PRODUCT_BETA_VERSION));
        return 	getProductVersionHolder(pvn,pn,ptn,v1,v2,v3,v4,bn,isBeta);
    }








    public static ProductVersionHolder
    getProductVersionHolder(
            String productVendorName,
            String productName,
            String productTechnologyName,
            int majorVersion,
            int minorVersion,
            int maintVersion,
            int drdaMaintVersion,
            String buildNumber,
            Boolean isBeta)
    {
        ProductVersionHolder pvh =
                new ProductVersionHolder(productVendorName,
                        productName,
                        productTechnologyName,
                        majorVersion,
                        minorVersion,
                        maintVersion,
                        drdaMaintVersion,
                        buildNumber,
                        isBeta);
        return pvh;
    }
    private ProductVersionHolder(String productVendorName,
                                 String productName,
                                 String productTechnologyName,
                                 int majorVersion,
                                 int minorVersion,
                                 int maintVersion,
                                 int drdaMaintVersion,
                                 String buildNumber,
                                 Boolean isBeta)
    {
        if (productVendorName != null)
            this.productVendorName = productVendorName.trim();
        if (productName != null)
            this.productName = productName.trim();
        if (productTechnologyName != null)
            this.productTechnologyName = productTechnologyName.trim();
        this.majorVersion = majorVersion;
        this.minorVersion = minorVersion;
        this.maintVersion = maintVersion;
        this.drdaMaintVersion = drdaMaintVersion;
        this.buildNumber = buildNumber;
        this.isBeta = isBeta;
    }

    private static int parseInt(String s)
    {

        //System.out.println("Parsing integer: "+s);
        int result = BAD_NUMBER;
        try
        {
            if (s!=null)
                result = Integer.parseInt(s);
        }
        catch (NumberFormatException nfe)
        {}

        if (result < 0) result = BAD_NUMBER;
        return result;
    }


}
